package com.aol.pubt.dynapubcms;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class CMSClient {
    public class Data {
        private String data;
        Data(String data) {
            this.data = data;
        }
        public String getData() {
            return data;
        }
    }
	private String templateName;
	private Map<String, String> overlays = new HashMap<String, String>();
	private Map<String, Data> data = new HashMap<String, Data>();
	private Map<String, Map<String, Data>> raw;
    public CMSClient() {
    	setTemplateName("default");
    }
    public CMSClient(String host, String templateName) {
    	checkNull(host);
    	setTemplateName(templateName);
    }
    public CMSClient(String templateName, String catType, String catId, String... overlays) {
    	setTemplateName(templateName);
    	overlay(catType, catId);
    	for (int i = 0; i < overlays.length - 1; i += 2) {
    		overlay(overlays[i], overlays[i + 1]);
    	}
    }
    public void setTemplateName(String templateName) {
    	checkNull(templateName);
    	this.templateName = templateName;
    	raw = null;
    	overlays.clear();
    	data.clear();
    }
    public String getTemplateName() {
    	return templateName;
    }
    public boolean overlay(String categoryTypeName, String categoryId) {
    	checkNull(categoryTypeName);
    	checkNull(categoryId);
    	if (raw == null) {
    		loadRawData();
    	}
    	String key = categoryTypeName + ":" + categoryId;
    	if (!raw.containsKey(key)) {
    		return false;
    	}
    	data.putAll(raw.get(key));
    	overlays.put(categoryTypeName, categoryId);
    	return true;
    }
    public Map<String, String> getOverlayList() {
    	return overlays;
    }
    public String getData(String slotName) {
    	checkNull(slotName);
    	if (raw == null) {
    		loadRawData();
    	}
    	return data.get(slotName) == null ? null : data.get(slotName).getData();
    }
    public Map<String, Data> getSlots() {
        return data;
    }
    public Properties getConfig(String slotName) {
    	Properties properties = new Properties();
    	try {
    		properties.load(new ByteArrayInputStream(getData(slotName).getBytes()));
    	} catch (IOException ioe) {
    	}
    	return properties;
    }
    private void checkNull(Object obj) {
    	if (obj == null) {
    		throw new RuntimeException();
    	}
    }
    private void loadRawData() {
    	try {
    		Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
    				this.getClass().getClassLoader().getResourceAsStream(templateName + ".xml"));
    		NodeList overlays = doc.getDocumentElement().getElementsByTagName("overlay");
    		raw = new HashMap<String, Map<String, Data>>();
    		for (int i = 0; i < overlays.getLength(); ++i) {
    			Element overlay = (Element) overlays.item(i);
    			Map<String, Data> data = new HashMap<String, Data>();
    			raw.put(overlay.getAttribute("key"), data);
    			NodeList slots = overlay.getElementsByTagName("slot");
    			for (int j = 0; j < slots.getLength(); ++j) {
    				Element slot = (Element) slots.item(j);
    				data.put(slot.getAttribute("name"), new Data(slot.getTextContent()));
    			}
    		}
    		if (raw.containsKey("default")) {
    			data.putAll(raw.get("default"));
    		}
    	} catch (Exception ex) {
    		throw new RuntimeException(ex);
    	}
    }
    public static void main(String[] args) {
    	CMSClient cms = new CMSClient();
    	cms.overlay("catType", "catId");
    	System.out.println(cms.getData("a"));
    	System.out.println(cms.getData("b"));
    	System.out.println(cms.getData("c"));
    	System.out.println(cms.getConfig("c").getProperty("a"));
    	System.out.println(cms.getConfig("c").getProperty("b"));
    }
}
